package side_server;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Vector;

import talk_server.SocketManager;
import data_structure.Address;
import data_structure.Collector;
import data_structure.Files;

public class Server_Launch implements Runnable{
	public final static String 		SEP = "_SEP_";
	private String					ip;
	private int						port;
	private String					localfolder;
	private ServerSocket			svrSocket;
	private Socket					cliSocket;
	private static Server_Launch	instance;
	
	public static Server_Launch getInstance()
	{
		if (instance==null) instance = new Server_Launch();
		return instance;
	}
	
	public Server_Launch()
	{
		super();
		ip="";
		port=0;
		localfolder="";
	}

	public void setPort(int port)
	{
		this.port=port;
	}
	
	public void setLocalFolder(String folder)
	{
		localfolder = folder;
	}
	
	public void setServerSocket(ServerSocket socket)
	{
		this.svrSocket=socket;
	}
	
	private void waitForConnection()
	{
		boolean running = true;
		System.out.println("************************");
		System.out.println("* PAGANET v 0.8.1 beta *");
		System.out.println("************************");
		
		Ping ping = new Ping();
		Thread t = new Thread(ping);
		t.start();
		
		while(running)
		{
			try {
				cliSocket = new Socket();
				cliSocket = svrSocket.accept();
				ip = cliSocket.getLocalAddress().getHostAddress(); // my IP
				//Prelevo l'IP e la porta dal Client
				String cliAddress = getClientAddressFromSocket(cliSocket);
				int    cliPort    = getClientPortFromSocket(cliSocket);
				System.out.println("IP:" + cliAddress + "  PORT:" + cliPort);
				//Creo un oggetto Address per conservare i dati
				Address addr = new Address(cliAddress, cliPort, cliSocket);
				String key = cliAddress + " " + cliPort;
				Collector.add(key,addr);
				SocketManager sm = new SocketManager(cliSocket);
				new Thread(sm).start();
			}
			catch (IOException e) {
				System.out.println("CONNESSIONE PERSA");
				running=false;
			}
		}
		ping.Stop();
	}
	
	public String getClientAddressFromSocket(Socket socket)
	{
		String ip   = socket.getLocalAddress().getHostAddress();
		return ip;
	}
	
	public int getClientPortFromSocket(Socket socket)
	{
		int port = socket.getLocalPort();
		return port;
	}
	
	public String getIp()
	{
		return this.ip;
	}
	
	public int getPort()
	{
		return this.port;
	}
	
	public String getServerAddress()
	{
		return this.ip + " " + this.getPort();
	}
	
	public String getPeerList() //return the peerlist in text format
	{
		String peerList="";
		HashSet<String> peers = Collector.getKeys();
		Iterator<String> it = peers.iterator();
		while(it.hasNext())
		{
			peerList += it.next() + SEP;
		}
		return peerList;
	}
	
	public void addPeer(String ip, int port)
	{
		Address o = new Address(ip, port);
		Collector.add(o.getPeerAddress(), o);
	}
	
	public void removePeer(String address)
	{
		Collector.remove(address);
	}
	
	public void removePeer(String ip, int port)
	{
		Collector.remove(ip + " " + port);
	}
	
	public String getLocalFolder()
	{
		return localfolder;
	}
	
	public Socket getSocket(String address)
	{
		return ((Address)Collector.get(address)).getSocket();
	}
	
	public void addSocket(String address,Socket socket)
	{
		((Address)Collector.get(address)).setSocket(socket);
	}
	
	public String getFiles()
	{
		String retFiles="";
		Vector<String> files = Files.getFiles(localfolder);
		for(int i=0;i<files.size();i++)
		{
			retFiles+=files.get(i) + Server.SEP;
		}
		return retFiles;
	}
	
	public void showPeers()
	{
		Iterator<String> it;
		it=Collector.iterator();
		System.out.println("\n\nELENCO PEERS");
		System.out.println("=================");
		while (it.hasNext())
		{
			System.out.println(it.next());
		}
		System.out.println("=================\n\n");
	}
	
	public void clearPeers()
	{
		Collector.clear();
	}
	
	public int getPeerCount()
	{
		return Collector.getCollection().size();
	}
	
	public HashSet<String> getKeys()
	{
		return Collector.getKeys();
	}
	
	@Override
	public void run() 
	{
		waitForConnection();
	}
}
